package com.dup.jxlh.admin.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.io.Serializable;

@Configuration
@EnableCaching
public class RedisConfig {
    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.redis.redis-0")
    public RedisStandaloneConfiguration redisStandaloneConfigurationA() {
        return new RedisStandaloneConfiguration();
    }

    @Bean("redisStandaloneConfigurationB")
    @ConfigurationProperties(prefix = "spring.redis.redis-1")
    public RedisStandaloneConfiguration redisStandaloneConfigurationB() {
        return new RedisStandaloneConfiguration();
    }

    @Bean("redisStandaloneConfigurationC")
    @ConfigurationProperties(prefix = "spring.redis.redis-2")
    public RedisStandaloneConfiguration redisStandaloneConfigurationC() {
        return new RedisStandaloneConfiguration();
    }

    @Bean
    @Primary
    public LettuceConnectionFactory lettuceConnectionFactoryA(@Autowired @Qualifier("redisStandaloneConfigurationA") RedisStandaloneConfiguration redisStandaloneConfigurationA) {
        return new LettuceConnectionFactory(redisStandaloneConfigurationA);
    }

    @Bean("lettuceConnectionFactoryB")
    public LettuceConnectionFactory lettuceConnectionFactoryB(@Autowired @Qualifier("redisStandaloneConfigurationB") RedisStandaloneConfiguration redisStandaloneConfigurationB) {
        return new LettuceConnectionFactory(redisStandaloneConfigurationB);
    }

    @Bean("lettuceConnectionFactoryC")
    public LettuceConnectionFactory lettuceConnectionFactoryC(@Autowired @Qualifier("redisStandaloneConfigurationC") RedisStandaloneConfiguration redisStandaloneConfigurationC) {
        return new LettuceConnectionFactory(redisStandaloneConfigurationC);
    }

    private RedisTemplate<String, Serializable> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
        RedisTemplate<String, Serializable> template = new RedisTemplate<>();
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.setConnectionFactory(lettuceConnectionFactory);
        return template;
    }

    @Bean
    @Primary
    public RedisTemplate<String, Serializable> redisTemplateA(@Autowired @Qualifier("lettuceConnectionFactoryA") LettuceConnectionFactory lettuceConnectionFactoryA) {
        return redisTemplate(lettuceConnectionFactoryA);
    }

    @Bean("redisTemplateB")
    public RedisTemplate<String, Serializable> redisTemplateB(@Autowired @Qualifier("lettuceConnectionFactoryB") LettuceConnectionFactory lettuceConnectionFactoryB) {
        return redisTemplate(lettuceConnectionFactoryB);
    }

    @Bean("redisTemplateC")
    public RedisTemplate<String, Serializable> redisTemplateC(@Autowired @Qualifier("lettuceConnectionFactoryC") LettuceConnectionFactory lettuceConnectionFactoryC) {
        return redisTemplate(lettuceConnectionFactoryC);
    }

    @Bean
    public RedisCacheManager cacheManager(@Autowired @Qualifier("lettuceConnectionFactoryA") LettuceConnectionFactory lettuceConnectionFactoryA) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));

        RedisCacheManager redisCacheManager = RedisCacheManager.builder(lettuceConnectionFactoryA)
                .cacheDefaults(config)
                .transactionAware()
                .build();
        return redisCacheManager;
    }
}